package com.le.edu.config;

import com.le.edu.properties.ThreadPoolConfigProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//@EnableConfigurationProperties(ThreadPoolConfigProperties.class)  //如果ioc容器没有ThreadPoolConfigProperties组件
@AutoConfiguration
public class MyThreadConfig {
    /**
     * 线程池七大参数：
     * 1.corePoolSize: 核心线程池大小；线程池，创建好以后就准备就绪的线程数量，就等待来接收异步任务区执行
     * 2.maximumPoolSize: 最大线程池大小；控制资源
     * 3.keepAliveTime: 存活时间；当线程池中超过corePoolSize线程，
     * 多余的空闲线程(maximumPoolSize-corePoolSize)的存活时间
     * 4.unit: 时间单位
     * 5.BlockingQueue<Runnable> workQueue: 阻塞队列。如果任务有很多，就会将目前多的任务放入到队列中
     * 只要线程空闲，就会去队列里面取出新的任务继续执行
     * 6.threadFactory: 线程的创建工厂
     * 7.handler: 如果队列满了，按照我们指定的指定策略拒绝执行任务
     * <p>
     * 运行流程：
     * 1、线程池创建，准备好 core 数量的核心线程，准备接受任务
     * 2、新的任务进来，用 core 准备好的空闲线程执行。
     * (1) 、core 满了，就将再进来的任务放入阻塞队列中。空闲的 core 就会自己去阻塞队
     * 列获取任务执行
     * (2) 、阻塞队列满了，就直接开新线程执行，最大只能开到 max 指定的数量
     * (3) 、max 都执行好了。Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自
     * 动销毁。最终保持到 core 大小
     * (4) 、如果线程数开到了 max 的数量，还有新任务进来，就会使用 reject 指定的拒绝策
     * 略进行处理
     * 3、所有的线程创建都是由指定的 factory 创建的。
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool) {
        return new ThreadPoolExecutor(pool.getCoreSize(),
                pool.getMaxSize(),
                pool.getKeepAlive(),
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}
